home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 025 (1987-08-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 025 (1987-08-15)(Ossowski, Stefan)(DE)(PD).adf / Graph / func.c < prev    next >
C/C++ Source or Header  |  1987-03-08  |  15KB  |  655 lines

  1. /****************************************************************************/
  2. /*   Program: Graph It II    (The C Program)                                    */
  3. /*   SubModule:    func.c  1-7-87                                                */
  4. /*   CopyRight By Flynn D. Fishman  January 1987                            */
  5. /*    Feel Free to copy and alter this source                                    */
  6. /****************************************************************************/
  7. /* This function includes all of the math related subroutines to solve all
  8.     the graph related problems                                                */
  9.  
  10. #include "graph.h"
  11. static char *(functions[]) = {"xx", "tt", "yy", "zz", "((", "))",
  12.                               "++", "--", "//", "^^", "==", "**",
  13.                               "ccos", "ssin", "Ttan", "eexp", "PPI", "EE",
  14.                               "aatan", "Sasin", "Cacos", "lln", "Aabs", "Ll",
  15.                               "end"};
  16.  
  17. double Solve(formula)
  18. struct Formula_Master *formula;
  19.   {
  20.   extern double x, y, z, t;
  21.   double lop, a, b, total;
  22.   char func;     
  23.  
  24.   a = 0;
  25.   b = 0;
  26.   total = Value(formula);
  27.  
  28.   while (formula->equation[formula->position] != '0' )
  29.     {
  30.     func = formula->equation[formula->position++];
  31.     if (func == 0) break;
  32.  
  33.     switch (func)
  34.       {
  35.       case '+':
  36.         total = total + Value(formula);
  37.        break;
  38.  
  39.       case '-':
  40.         total = total - Value(formula);
  41.        break;
  42.  
  43.       case '*':
  44.         total = total * Value(formula);
  45.        break;
  46.  
  47.       case '/':
  48.         a = Value(formula);
  49.         if (a != 0) total = total / a;
  50.         else total = INFINITY;
  51.        break;
  52.  
  53.       case '^':
  54.         total = pow(total, Value(formula) );
  55.        break;
  56.  
  57.       case '=':
  58.         total = (total == Value(formula) );
  59.        break;
  60.  
  61.       case '\)':
  62.         return(total);
  63.        break;
  64.  
  65.       default:
  66.           formula->error = INVALID;
  67.         return(0);
  68.  
  69.       } /* end of case */
  70.     }  /* end of while */
  71.  
  72.   return (total);
  73.   }  /* end of Solve */
  74.  
  75. double Value(formula)
  76. struct Formula_Master *formula;
  77.     {
  78.     extern double x, y, z, t;
  79.     int whichfunc, position;
  80.     double a,b;
  81.     char test, bitmask, tmp, lowmask, highbit;
  82.  
  83.     position = formula->position;
  84.  
  85.     test = formula->equation[formula->position];
  86.     if (test == '\(')
  87.         {
  88.         formula->position++;
  89.         return(Solve(formula));
  90.         }
  91.  
  92.     tmp = (test & HIGHBIT);
  93.     if (tmp != 0)
  94.         {
  95.         return (
  96.                 formula->constants[
  97.                    LOWMASK & formula->equation[formula->position++]
  98.                                   ]
  99.                 );
  100.         }
  101.     formula->position++;
  102.  
  103.     switch (test)
  104.     {
  105.     case '\(':  /* ( */ 
  106.       return(Solve(formula));
  107.     break;
  108.  
  109.     case 'x':  /* X */ 
  110.       return(x);
  111.     break;
  112.  
  113.     case 'y':  /* Y */
  114.       return(y);
  115.     break;
  116.  
  117.     case 't':  /* T */
  118.       return(t);
  119.     break;
  120.  
  121.     case 'z':  /* Z */
  122.       return(z);
  123.     break;
  124.  
  125.     case 'c':  /* Cos */
  126.       return (cos ( Value (formula) ) );
  127.     break;
  128.  
  129.     case 's':  /* Sin */
  130.       return (sin ( Value (formula) ) );
  131.     break;
  132.  
  133.     case 'T':  /* Tan */
  134.       return (tan ( Value (formula) ) );
  135.     break;
  136.  
  137.     case 'e':  /* E to the x */
  138.       return ( exp ( Value(formula) ) );
  139.     break;
  140.  
  141.     case 'P':  /* PI */
  142.       return ( PI );
  143.     break;
  144.  
  145.     case 'E':  /* E to the x */
  146.       return ( exp (1.0) );
  147.     break;
  148.  
  149.     case 'l': /* ln */
  150.       return ( log ( Value(formula) ) );
  151.     break;
  152.  
  153.     case 'a': /* Atan */
  154.       return ( atan ( Value(formula) ) );
  155.     break;
  156.  
  157.     case 'S': /* Asin */
  158.       return ( asin ( Value(formula) ) );
  159.     break;
  160.  
  161.     case 'C': /* Acos */
  162.       return ( acos ( Value(formula) ) );
  163.     break;
  164.  
  165.     case 'A': /* abs */
  166.       return ( abs ( Value(formula) ) );
  167.     break;
  168.  
  169.     default:
  170.       formula->error = UNKNOWN;
  171.       return(0);
  172.     } /* end of switch */
  173.  
  174.   } /* end of routine */
  175.  
  176. GetFunction(infile, formula)
  177. FILE *infile;
  178. struct Formula_Master *formula;
  179.     {
  180.     char text[50], inchar;
  181.     double a;
  182.     int position, lasttype, function, constants, whichfunc;
  183.  
  184.     position = 0;
  185.     function = 0;
  186.     constants = 0;
  187.  
  188.     while ( (inchar = getc(infile) ) == ' ');
  189.     lasttype = Type(inchar);
  190.     for ever
  191.       {
  192.       if ((lasttype == Type(inchar)) && (inchar != ' '))
  193.           {
  194.           text[position++] = inchar;
  195.         }
  196.     else
  197.         {
  198.         text[position] = 0;
  199.  
  200.         if (lasttype == ALPHA) 
  201.             {
  202.               for (whichfunc = 0;
  203.                    strcmp(text, &functions[whichfunc][1]) ;
  204.                    whichfunc++)
  205.                 {
  206.                 if (!strcmp( functions[whichfunc], "end") )
  207.                       {
  208.                       return(FALSE);
  209.                       }
  210.                 }
  211.               formula->equation[function++] = functions[whichfunc][0];
  212.             }
  213.  
  214.             if (lasttype == NUMERIC) 
  215.                 {
  216.                 formula->equation[function++] = (HIGHBIT | constants);
  217.                 sscanf(text, "%f", &a );
  218.                 formula->constants[constants++] =  a;
  219.                 }
  220.  
  221.             if (lasttype == OTHER) 
  222.                 {
  223.                 position = 0;
  224.                 while (text[position] !=0)
  225.                     {
  226.                     formula->equation[function++] = text[position++];
  227.                     }
  228.                 }
  229.  
  230.             if (inchar == ' ') while ( (inchar = getc(infile) ) == ' ');
  231.             position = 0;
  232.             text[position++] = inchar;
  233.             lasttype = Type(inchar);
  234.             }  /* end of else */
  235.  
  236.         if (lasttype == END) break;
  237.         inchar = getc(infile);
  238.  
  239.           }      /* end of forever */
  240.  
  241.     formula->equation[function] = 0;
  242.     if (function == 0)
  243.         {
  244.         FreeFunction(formula);
  245.         return(FALSE);
  246.         }
  247.     return(TRUE);
  248.     }        /* end of routine */
  249.  
  250. Type(character)
  251. char character;
  252.     {
  253.     if(character >= 'a' && character <= 'z') return (ALPHA);
  254.     if(character >= 'A' && character <= 'Z') return (ALPHA);
  255.     if(character >= '0' && character <= '9') return (NUMERIC);
  256.     if(character == '.') return (NUMERIC);
  257.        if(character == ';' || character == '\n' || character == '\r'
  258.         || character == EOF) return(END);
  259.     return(OTHER);
  260.     }
  261.  
  262. SetDefaults(parameters)
  263. struct Graph_Parameters *parameters;
  264.     {
  265.     parameters->end = FALSE;
  266.  
  267.     parameters->xstart = -5.0;
  268.     parameters->ystart = -5.0;
  269.     parameters->zstart = -5.0;
  270.     parameters->tstart = -5.0;
  271.  
  272.     parameters->xend = 5.0;
  273.     parameters->yend = 5.0;
  274.     parameters->zend = 5.0;
  275.     parameters->tend = 5.0;
  276.  
  277.     parameters->xlabels = 1.0;
  278.     parameters->ylabels = 1.0;
  279.     parameters->zlabels = 1.0;
  280.  
  281.     parameters->detail = 1.0;
  282.     }
  283.  
  284. GetVariables(Window, parameters, infile)
  285. struct Window *Window;
  286. struct Graph_Parameters *parameters;
  287. FILE *infile;
  288.     {
  289.     char inchar, variable, command;
  290.     double number;
  291.     long int minx, miny, maxx, maxy;
  292.  
  293.     minx = Window->BorderLeft;
  294.     miny = Window->BorderTop;
  295.     maxx = Window->Width - Window->BorderRight - XBORDER;
  296.     maxy = Window->Height - Window->BorderBottom - YBORDER;
  297.  
  298.     for ever
  299.         {
  300.         DrawRectangle(Window, 1l, minx, miny, maxx, miny+110);
  301.         DisplayVariables(Window, parameters);
  302.         variable = getc(infile);
  303.         if (variable == '\r' || variable == '\n' || variable == 'e') break;
  304.         if (variable != 'd' || variable != 'h' ) command = getc(infile);
  305.         if (command == '=' || variable == 'h') command = '1';
  306.         else while ( (inchar = getc(infile) ) != '=' );
  307.  
  308.         if (command < '0' || command > '9')
  309.             {
  310.             number = GetNum(infile);
  311.             if (number != 0.0)
  312.                 {
  313.                 if(variable== 'd') parameters->detail = number;
  314.                 if(variable== 'h')
  315.                     parameters->hidden = (parameters->hidden) ? FALSE : TRUE;
  316.  
  317.                 if(variable== 'x' && command== 's')parameters->xstart = number;
  318.                 if(variable== 'x' && command== 'e')parameters->xend = number;
  319.                 if(variable== 'x' && command== 'l')parameters->xlabels =number;
  320.  
  321.                 if(variable== 'y' && command== 's')parameters->ystart = number;
  322.                 if(variable== 'y' && command== 'e')parameters->yend = number;
  323.                 if(variable== 'y' && command== 'l')parameters->ylabels =number;
  324.  
  325.                 if(variable== 'z' && command== 's')parameters->zstart = number;
  326.                 if(variable== 'z' && command== 'e')parameters->zend = number;
  327.                 if(variable== 'z' && command== 'l')parameters->zlabels =number;
  328.  
  329.                 if(variable== 't' && command== 's')parameters->tstart = number;
  330.                 if(variable== 't' && command== 'e')parameters->tend = number;
  331.                 } /* end of 0.0 else */
  332.             }    /* end of if not equation */
  333.         else    /* Its a formula */
  334.             {
  335.             if (variable == 'x')
  336.                 {
  337.                 if (!parameters->xon) parameters->x1 = AllocateFunction();
  338.                 if (parameters->x1 != NULL)
  339.                     {
  340.                     if (!GetFunction(infile, parameters->x1))
  341.                         {
  342.                         parameters->xon = FALSE;
  343.                         error(Window, FALSE);
  344.                         }
  345.                     else
  346.                         {
  347.                         parameters->xon = TRUE;
  348.                         parameters->x1->position=0;
  349.                         parameters->x1->error = FALSE;
  350.                         Solve(parameters->x1);
  351.                         if (parameters->x1->error != FALSE)
  352.                             error(Window, parameters->x1->error);
  353.                         }
  354.                     }
  355.                 }    /* end of x = */
  356.             if (variable == 'y')
  357.                 {
  358.                 if (!parameters->yon) parameters->y1 = AllocateFunction();
  359.                 if (parameters->y1 != NULL)
  360.                     {
  361.                     if (!GetFunction(infile, parameters->y1))
  362.                         {
  363.                         parameters->yon = FALSE;
  364.                         error(Window, FALSE);
  365.                         }
  366.                     else
  367.                         {
  368.                         parameters->yon = TRUE;
  369.                         parameters->y1->position=0;
  370.                         parameters->y1->error = FALSE;
  371.                         Solve(parameters->y1);
  372.                         if (parameters->y1->error != FALSE)
  373.                             error(Window, parameters->y1->error);
  374.                         }
  375.                     }
  376.                 }    /* end of y = */
  377.             if (variable == 'z')
  378.                 {
  379.                 if (!parameters->zon) parameters->z1 = AllocateFunction();
  380.                 if (parameters->z1 != NULL)
  381.                     {
  382.                     if (!GetFunction(infile, parameters->z1))
  383.                         {
  384.                         parameters->zon = FALSE;
  385.                         error(Window, FALSE);
  386.                         }
  387.                     else
  388.                         {
  389.                         parameters->zon = TRUE;
  390.                         parameters->z1->position=0;
  391.                         parameters->z1->error = FALSE;
  392.                         Solve(parameters->z1);
  393.                         if (parameters->z1->error != FALSE)
  394.                             error(Window, parameters->z1->error);
  395.                         }
  396.                     }
  397.                 }    /* end of z = */
  398.             }  /* end of else */
  399.  
  400.         } /* end of for ever */
  401.     }     /* end of command */
  402.  
  403. error(Window, error)
  404. struct Window *Window;
  405. int error;
  406.     {
  407.     long int minx, miny, maxx, maxy;
  408.  
  409.     minx = Window->BorderLeft;
  410.     miny = Window->BorderTop;
  411.     maxx = Window->Width - Window->BorderRight - XBORDER;
  412.     maxy = Window->Height - Window->BorderBottom - YBORDER;
  413.  
  414.     DrawRectangle(Window, 3l, minx, miny+10, maxx, miny+115);
  415.     SetAPen(Window->RPort, 1l);
  416.     if (error == INVALID) Print(Window, "Invalid Function was entered", 13l);
  417.     else if (error == UNKNOWN)
  418.             Print(Window, "An unknown Function was entered", 13l);
  419.     else if (error == FALSE)
  420.             Print(Window, "An unknown Function was entered", 13l);
  421.     }
  422.  
  423. double GetNum(infile)
  424. FILE *infile;
  425.     {
  426.     char inchar, text[20];
  427.     int position;
  428.     double a;
  429.  
  430.     position = 0;
  431.     inchar = getc(infile);
  432.     while (Type(inchar) != END)
  433.         {
  434.         text[position++] = inchar;
  435.         inchar = getc(infile);
  436.         }
  437.     text[position] = 0;
  438.     sscanf(text, "%f", &a );
  439.     return(a);
  440.     }
  441.  
  442. char *AllocateFunction()
  443.     {
  444.     struct Formula_Master *formula;
  445.  
  446.     formula = AllocMem( (long) sizeof(struct Formula_Master), 0);
  447.     if (formula == NULL) return(0);
  448.  
  449.     formula->equation = AllocMem(sizeof(char) * FSIZE , 0);
  450.     if (formula->equation == NULL) return(0);
  451.  
  452.     formula->constants = AllocMem(sizeof(double) * CONSTANTS , 0);
  453.     if (formula->constants == NULL) return(0);
  454.  
  455.     return(formula);
  456.     }
  457.  
  458. FreeFunction(formula)
  459. struct Formula_Master *formula;
  460.     {
  461.     FreeMem(formula->equation, sizeof(char) * FSIZE);
  462.     FreeMem(formula->constants, sizeof(double) * CONSTANTS);
  463.     FreeMem(formula, sizeof (struct Formula_Master) );
  464.     }
  465.  
  466. GetCommand(Window, parameters)
  467. struct Window *Window;
  468. struct Graph_Parameters *parameters;
  469.     {
  470.     FILE *infile;
  471.     char list[80];
  472.  
  473.     infile = fopen("con:0/140/640/36/Enter Command", "r");
  474.     if (infile == NULL)
  475.         {
  476.         parameters->error = WINDOW;
  477.         return(0);
  478.         }
  479.  
  480.     GetVariables(Window, parameters, infile);
  481.  
  482.     fclose(infile);
  483.     }
  484.  
  485. LoadFile(Window, parameters)
  486. struct Window *Window;
  487. struct Graph_Parameters *parameters;
  488.     {
  489.     FILE *infile;
  490.     char line[80], file[40];
  491.  
  492.     GetFileName(line);
  493.  
  494.     infile = fopen(line, "r");
  495.     if (infile == NULL) return();
  496.  
  497.     GetVariables(Window, parameters, infile);
  498.     fclose(infile);
  499.     }
  500.  
  501. SaveFile(Window, parameters)
  502. struct Window *Window;
  503. struct Graph_Parameters *parameters;
  504.     {
  505.     FILE *outfile;
  506.     char line[80], file[40];
  507.  
  508.     GetFileName(line);
  509.  
  510.     outfile = fopen(line, "w");
  511.     if (outfile == NULL) return();
  512.  
  513.     fprintf(outfile, "xstart=%f\n", parameters->xstart);
  514.     fprintf(outfile, "ystart=%f\n", parameters->ystart);
  515.     fprintf(outfile, "zstart=%f\n", parameters->zstart);
  516.     fprintf(outfile, "tstart=%f\n", parameters->tstart);
  517.     fprintf(outfile, "xend=%f\n", parameters->xend);
  518.     fprintf(outfile, "yend=%f\n", parameters->yend);
  519.     fprintf(outfile, "zend=%f\n", parameters->zend);
  520.     fprintf(outfile, "tend=%f\n", parameters->tend);
  521.     fprintf(outfile, "xlabels=%f\n", parameters->xlabels);
  522.     fprintf(outfile, "ylabels=%f\n", parameters->ylabels);
  523.     fprintf(outfile, "zlabels=%f\n", parameters->zlabels);
  524.     fprintf(outfile, "detail=%f\n", parameters->detail);
  525.  
  526.     if(parameters->xon)
  527.         {
  528.         Expand(parameters->x1, line);
  529.         fprintf(outfile, "x1=%s\n", line);
  530.         }
  531.     if(parameters->yon)
  532.         {
  533.         Expand(parameters->y1, line);
  534.         fprintf(outfile, "y1=%s\n", line);
  535.         }
  536.     if(parameters->zon)
  537.         {
  538.         Expand(parameters->z1, line);
  539.         fprintf(outfile, "z1=%s\n", line);
  540.         }
  541.  
  542.     fprintf(outfile,"e\n");
  543.  
  544.     fclose(outfile);
  545.     }
  546.  
  547. GetFileName(line)
  548. char line[];
  549.     {
  550.     FILE *infile;
  551.     char inchar;
  552.     int position;
  553.  
  554.     infile = fopen("con:0/140/640/24/Please Enter Filename:", "r");
  555.     if (infile == NULL) return(0);
  556.  
  557.     position = 0;
  558.     inchar = getc(infile);
  559.     while ( Type(inchar) != END)
  560.         {
  561.         line[position++] = inchar;
  562.         inchar = getc(infile);
  563.         }
  564.  
  565.     line[position] = 0;
  566.     fclose(infile);
  567.     }
  568.  
  569. DisplayVariables(Window, parameters)
  570. struct Window *Window;
  571. struct Graph_Parameters *parameters;
  572.     {
  573.     char line[80], tmp[80];
  574.  
  575.     SetAPen(Window->RPort, 3l);
  576.     SetBPen(Window->RPort, 0l);
  577.     SetDrMd(Window->RPort, JAM2);
  578.     Print(Window, "Current Variable Settings", 0);
  579.     sprintf(line, "  start        end          labels       other       ");
  580.     Print(Window, line, 1);
  581.     sprintf(line,"x:%4.6f %4.6f %4.6f",parameters->xstart, parameters->xend,
  582.                                          parameters->xlabels);
  583.     Print(Window, line, 2);
  584.     sprintf(line, "y:%4.6f %4.6f %4.6f", parameters->ystart, parameters->yend,
  585.                                          parameters->ylabels);
  586.     Print(Window, line, 3);
  587.     sprintf(line, "z:%4.6f %4.6f %4.6f", parameters->zstart, parameters->zend,
  588.                                          parameters->zlabels);
  589.     Print(Window, line, 4);
  590.     sprintf(line, "t:%4.6f %4.6f  N/A", parameters->tstart, parameters->tend);
  591.     Print(Window, line, 5);
  592.  
  593.     sprintf(line, "Detail is %4.6f", parameters->detail);
  594.     Print(Window, line, 6);
  595.  
  596.     if(parameters->hidden) Print(Window, "Hidden lines is ON ", 7);
  597.     else Print(Window, "Hidden lines is OFF", 7);
  598.  
  599.     if (parameters->xon)
  600.         {
  601.         Expand(parameters->x1, line);
  602.         sprintf(tmp, "x=");
  603.         strcat (tmp, line);
  604.         strcat (tmp, "  ");
  605.         Print(Window, tmp, 9);
  606.         }
  607.     if (parameters->yon)
  608.         {
  609.         Expand(parameters->y1, line);
  610.         sprintf(tmp, "y=");
  611.         strcat (tmp, line);
  612.         strcat (tmp, "  ");
  613.         Print(Window, tmp, 10);
  614.         }
  615.     if (parameters->zon)
  616.         {
  617.         Expand(parameters->z1, line);
  618.         sprintf(tmp, "z=");
  619.         strcat (tmp, line);
  620.         strcat (tmp, "  ");
  621.         Print(Window, tmp, 11);
  622.         }
  623.     }
  624.  
  625. Expand(formula, line)
  626. struct Formula_Master *formula;
  627. char line[];
  628.     {
  629.     int loop, position;
  630.     char tmp[30];
  631.  
  632.     line[0]=0;
  633.  
  634.     for (position = 0; position < strlen(formula->equation); position++)
  635.         {
  636.         if ((formula->equation[position] & HIGHBIT) != 0)
  637.             {
  638.             sprintf(tmp, "%f",
  639.                 formula->constants[LOWMASK & formula->equation[position]]);
  640.             strcat(line, tmp);
  641.             }
  642.         else
  643.             {
  644.             loop = 0;
  645.             /* is this wrong ?    */
  646.             while (strcmp(functions[loop], "end") )
  647.                 {
  648.                 if (functions[loop][0] == formula->equation[position])
  649.                     strcat(line, &functions[loop][1]);
  650.                 loop++;
  651.                 }    /* end of while    */
  652.             }    /* end of else    */
  653.         }    /* end of for    */
  654.     }        /* end of the routine    */
  655.